package com.zywl.utils.utils;

import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.CharArrayBuffer;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;

import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @Author: 杨帆
 * @Date: 2019/6/11 15:23
 * @Description:
 */
public class HttpUtil {
    private static final Logger logger = Logger.getLogger(HttpUtil.class);

    /**
     * 发送post请求，参数用map接收
     *  
     *
     * @param url       地址
     * @param condition 参数
     * @return 返回值
     */
    public static String postMap(String url, Map<String, String> condition) {
        String result = null;
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpPost post = new HttpPost(url);
        List<NameValuePair> pairs = new ArrayList<NameValuePair>();
        for (Map.Entry<String, String> entry : condition.entrySet()) {
            pairs.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
        }
        CloseableHttpResponse response = null;
        try {
            post.setEntity(new UrlEncodedFormEntity(pairs, "UTF-8"));
            response = httpClient.execute(post);
            if (response != null && response.getStatusLine().getStatusCode() == 200) {
                HttpEntity entity = response.getEntity();
                result = entityToString(entity);
            }
            return result;
        } catch (Exception e) {
            logger.error("发送post请求异常", e);
        } finally {
            try {
                httpClient.close();
                if (response != null) {
                    response.close();
                }
            } catch (IOException e) {
            }
        }
        return null;
    }

    /**
     * 发送post请求，参数用json接收
     *  
     *
     * @param url  地址
     * @param json 参数
     * @return 返回值
     */
    public static String postMap(String url, String json) {
        String result = null;
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpPost post = new HttpPost(url);
        CloseableHttpResponse response = null;
        try {
            post.setEntity(new StringEntity(json, "UTF-8"));
            post.setHeader("Content-type", "application/json");
            return httpClient.execute(post, new BasicResponseHandler());
        } catch (Exception e) {
            logger.error("发送post请求异常", e);
        } finally {
            try {
                httpClient.close();
                if (response != null) {
                    response.close();
                }
            } catch (IOException e) {
            }
        }
        return null;
    }

    /**
     * get请求，参数拼接在地址上
     *
     * @param url 请求地址加参数
     * @return 响应
     */
    public static String get(String url) {
        String result = null;
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpGet get = new HttpGet(url);
        CloseableHttpResponse response = null;
        try {
            response = httpClient.execute(get);
            if (response != null && response.getStatusLine().getStatusCode() == 200) {
                HttpEntity entity = response.getEntity();
                result = entityToString(entity);
            }
            return result;
        } catch (Exception e) {
            logger.error("发送get请求异常", e);
        } finally {
            try {
                httpClient.close();
                if (response != null) {
                    response.close();
                }
            } catch (IOException e) {
            }
        }
        return null;
    }

    /**
     * get请求，参数放在map里
     *
     * @param url 请求地址
     * @param map 参数map
     * @return 响应
     */
    public static String get(String url, Map<String, String> map) {
        String result = null;
        CloseableHttpClient httpClient = HttpClients.createDefault();
        List<NameValuePair> pairs = new ArrayList<NameValuePair>();
        for (Map.Entry<String, String> entry : map.entrySet()) {
            pairs.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
        }
        CloseableHttpResponse response = null;
        try {
            URIBuilder builder = new URIBuilder(url);
            builder.setParameters(pairs);
            HttpGet get = new HttpGet(builder.build());
            response = httpClient.execute(get);
            if (response != null && response.getStatusLine().getStatusCode() == 200) {
                HttpEntity entity = response.getEntity();
                result = entityToString(entity);
            }
            return result;
        } catch (Exception e) {
            logger.error("发送get请求异常", e);
        } finally {
            try {
                httpClient.close();
                if (response != null) {
                    response.close();
                }
            } catch (IOException e) {
            }
        }
        return null;
    }

    /**
     * http接口上传单一文件
     *
     * @param url       请求路径
     * @param localFile 文件路径
     * @param param     参数
     */
    public static String uploadFile(String url, String localFile, Map<String, String> param) {
        String result = null;
        CloseableHttpClient httpClient = null;
        CloseableHttpResponse response = null;
        try {
            httpClient = HttpClients.createDefault();
            // 把一个普通参数和文件上传给下面这个地址 是一个servlet
            HttpPost httpPost = new HttpPost(url);
            //把文件转换成流对象FileBody
            File file = new File(localFile.replace(Constants.STRING_SPRIT, File.separator));
            FileBody fundFileBin = new FileBody(file);
            MultipartEntityBuilder builder = MultipartEntityBuilder.create().setMode(HttpMultipartMode.RFC6532);
            // 相当于<input type="file" name="file"/>
            builder.addPart(file.getName(), fundFileBin);
            if (param != null) {
                for (Map.Entry<String, String> entry : param.entrySet()) {
                    String key = entry.getKey();
                    // 相当于<input type="text" name="userName" value=userName>
                    StringBody value = new StringBody(entry.getValue(), ContentType.create("text/plain", Consts.UTF_8));
                    builder.addPart(key, value);
                }
            }
            HttpEntity reqEntity = builder.build();

            httpPost.setEntity(reqEntity);

            // 发起请求 并返回请求的响应
            response = httpClient.execute(httpPost);
            if (response != null) {
                HttpEntity entity = response.getEntity();
                result = entityToString(entity);
                EntityUtils.consume(entity);
            }
            return result;
        } catch (Exception e) {
            logger.error("http接口上传文件异常", e);
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
            } catch (IOException e) {
            }
            try {
                if (httpClient != null) {
                    httpClient.close();
                }
            } catch (IOException e) {
            }
        }
        return null;
    }

    /**
     * http接口上传单一文件
     *
     * @param url       请求路径
     * @param localFile 文件路径
     * @param fieldId   相当于<input type="file" name="file"/>
     * @param param     参数
     */
    public static String uploadFile(String url, String localFile, String fieldId, Map<String, String> param) {
        String result = null;
        CloseableHttpClient httpClient = null;
        CloseableHttpResponse response = null;
        try {
            httpClient = HttpClients.createDefault();
            // 把一个普通参数和文件上传给下面这个地址 是一个servlet
            HttpPost httpPost = new HttpPost(url);
            //把文件转换成流对象FileBody
            File file = new File(localFile.replace(Constants.STRING_SPRIT, File.separator));
            FileBody fundFileBin = new FileBody(file);
            MultipartEntityBuilder builder = MultipartEntityBuilder.create().setMode(HttpMultipartMode.RFC6532);
            // 相当于<input type="file" name="file"/>
            builder.addPart(fieldId, fundFileBin);
            if (param != null) {
                for (Map.Entry<String, String> entry : param.entrySet()) {
                    String key = entry.getKey();
                    // 相当于<input type="text" name="userName" value=userName>
                    StringBody value = new StringBody(entry.getValue(), ContentType.create("text/plain", Consts.UTF_8));
                    builder.addPart(key, value);
                }
            }
            HttpEntity reqEntity = builder.build();

            httpPost.setEntity(reqEntity);

            // 发起请求 并返回请求的响应
            response = httpClient.execute(httpPost);
            if (response != null) {
                HttpEntity entity = response.getEntity();
                result = entityToString(entity);
                EntityUtils.consume(entity);
            }
            return result;
        } catch (Exception e) {
            logger.error("http接口上传文件异常", e);
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
            } catch (IOException e) {
            }
            try {
                if (httpClient != null) {
                    httpClient.close();
                }
            } catch (IOException e) {
            }
        }
        return null;
    }

    /**
     * .http接口上传多文件
     *
     * @param url       请求路径
     * @param filePaths 文件路径
     * @param param     参数
     * @return
     */
    public static String uploadFiles(String url, List<String> filePaths, Map<String, String> param) {
        String result = null;
        CloseableHttpClient httpClient = null;
        CloseableHttpResponse response = null;
        try {
            httpClient = HttpClients.createDefault();
            // 把一个普通参数和文件上传给下面这个地址 是一个servlet
            HttpPost httpPost = new HttpPost(url);

            MultipartEntityBuilder builder = MultipartEntityBuilder.create().setMode(HttpMultipartMode.RFC6532);
            // 相当于<input type="file" name="file"/>
            File file = null;
            FileBody fundFileBin = null;
            for (String filePath : filePaths) {
                file = new File(filePath.replace(Constants.STRING_SPRIT, File.separator));
                fundFileBin = new FileBody(file);
                builder.addPart(file.getName(), fundFileBin);
            }
            if (param != null) {
                for (Map.Entry<String, String> entry : param.entrySet()) {
                    String key = entry.getKey();
                    // 相当于<input type="text" name="userName" value=userName>
                    StringBody value = new StringBody(entry.getValue(), ContentType.create("text/plain", Consts.UTF_8));
                    builder.addPart(key, value);
                }
            }
            HttpEntity reqEntity = builder.build();

            httpPost.setEntity(reqEntity);

            // 发起请求 并返回请求的响应
            response = httpClient.execute(httpPost);
            if (response != null) {
                HttpEntity entity = response.getEntity();
                result = entityToString(entity);
                EntityUtils.consume(entity);
            }
            return result;
        } catch (Exception e) {
            logger.error("http接口上传文件异常", e);
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
            } catch (IOException e) {
            }
            try {
                if (httpClient != null) {
                    httpClient.close();
                }
            } catch (IOException e) {
            }
        }
        return null;
    }

    /**
     * 对象转string
     *
     * @param entity
     * @return
     * @throws Exception
     */
    private static String entityToString(HttpEntity entity) throws Exception {
        String result = null;
        if (entity != null) {
            long lenth = entity.getContentLength();
            if (lenth != -1 && lenth < 2048) {
                result = EntityUtils.toString(entity, "UTF-8");
            } else {
                InputStreamReader reader1 = new InputStreamReader(entity.getContent(), "UTF-8");
                CharArrayBuffer buffer = new CharArrayBuffer(2048);
                char[] tmp = new char[1024];
                int l;
                while ((l = reader1.read(tmp)) != -1) {
                    buffer.append(tmp, 0, l);
                }
                result = buffer.toString();
            }
        }
        return result;
    }
}
